import gi
gi.require_version('Gst', '1.0')
from gi.repository import Gst, GLib
import numpy as np
import threading
from queue import Queue
from PIL import Image

# 初始化GStreamer
Gst.init(None)

# 全局帧队列（线程安全）
frame_queue = Queue(maxsize=100)  # 缓冲100帧

# RTSP摄像头URL列表
rtsp_urls = [
     "rtsp://admin:lxy888888@192.168.1.249:554/Streaming/Channels/101",
     "rtsp://admin:lxy888888@192.168.1.240:554/Streaming/Channels/101",
     "rtsp://admin:lxy888888@192.168.1.241:554/Streaming/Channels/101",
     "rtsp://admin:lxy888888@192.168.1.242:554/Streaming/Channels/101",
     "rtsp://admin:lxy888888@192.168.1.243:554/Streaming/Channels/101"
    # 添加更多摄像头...
]

# 定义GStreamer管道模板（硬件加速版）
pipeline_template = """
    rtspsrc location={url} latency=20 drop-on-latency=true ! 
    rtph264depay ! h264parse ! mppvideodec format=RGB discard-corrupted-frames=true ! video/x-raw,format=RGB !  
    appsink name=sink_{id} emit-signals=true sync=false
"""

def on_new_sample(appsink, id):
    """从appsink提取帧并放入队列"""
    sample = appsink.emit("pull-sample")
    if not sample:
        return Gst.FlowReturn.ERROR
  
    # 将GStreamer buffer转为numpy数组
    buffer = sample.get_buffer()
    width, height = 2560, 1440  # 根据实际分辨率调整
    frame = np.frombuffer(buffer.extract_dup(0, buffer.get_size()), dtype=np.uint8)
    frame = frame.reshape(height, width, 3)  # RGB格式
    print(id)
    return Gst.FlowReturn.OK

def start_pipeline(url,camera_id,idx):
    """启动单路RTSP流的解码管道"""
    pipeline_str = pipeline_template.format(url=url,id=idx)
    pipeline = Gst.parse_launch(pipeline_str)
    appsink = pipeline.get_by_name("sink_{id}".format(id=idx))
    print(f"绑定摄像头 {camera_id} 的回调函数...")  # 调试输出
    # 设置回调函数
    appsink.connect("new-sample", lambda sink: on_new_sample(sink,camera_id))

    # 启动管道
    pipeline.set_state(Gst.State.PLAYING)
    return pipeline
   
def bus_call(bus, message, loop):
    t = message.type
    if t == Gst.MessageType.ERROR:
        err, debug = message.parse_error()
        print(f"[ERROR] From element: {message.src.get_name()}")
        print(f"Error message: {err}")
        print(f"Debug info: {debug}")
        loop.quit()  # 如果想在出错时停止主循环
    elif t == Gst.MessageType.EOS:
        print("[EOS] End-Of-Stream reached")
        loop.quit()
    elif t == Gst.MessageType.WARNING:
        err, debug = message.parse_warning()
        print(f"[WARNING] From element: {message.src.get_name()}")
        print(f"Warning message: {err}")
        print(f"Debug info: {debug}")
    # 你还可以监听其他消息类型，比如 INFO、STATE_CHANGED等
    return True

if __name__ == "__main__":
    # 你已有代码启动管道部分，示例给一个管道bus添加监听
    pipelines = []
    loop = GLib.MainLoop()

    for idx, url in enumerate(rtsp_urls):
        pipeline = start_pipeline(url, f"camera-{idx}",idx)
        pipelines.append(pipeline)

        bus = pipeline.get_bus()
        bus.add_signal_watch()
        bus.connect("message", bus_call, loop)

    try:
        loop.run()
    except KeyboardInterrupt:
        loop.quit()
        for pipeline in pipelines:
            pipeline.set_state(Gst.State.NULL)